import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Table from './Table';
import { HeaderColumnType, RowDataType } from './Table.types';
import './Table.stories.css';

const rowArray: RowDataType[] = [
    {
        id: 1,
        disabled: false,
        name: "Василий",
        family: "Васькин",
        surname: "Васильевич",
        actions: <button type='button' style={{ marginLeft: "1rem" }}>Ok-1</button>
    }
];

const rowDisabledArray: RowDataType[] = [
    {
        id: 1,
        disabled: true,
        name: "Василий",
        family: "Васькин",
        surname: "Васильевич",
        actions: <button type='button' style={{ marginLeft: "1rem" }}>Ok-1</button>
    }
];

const headerArray: HeaderColumnType[] = [
    {
        title: "ID",
        name: "id"
    },
    {
        title: "Имя",
        name: "name"
    },
    {
        title: "Фамилия",
        name: "family"
    },
    {
        title: "Отчество",
        name: "surname"
    },
    {
        title: "Actions",
        name: "actions"
    }
];

describe('Table', () => {

    test('should renders column headers', () => {
        render(<Table columnList={[{ title: 'Name', name: 'name' }]} />);

        const header = screen.getByRole('columnheader', { name: /name/i });
        expect(header).toBeInTheDocument();
    });

    test('should renders rows', () => {
        render(<Table rowList={[{ id: 1, name: 'John' }]} columnList={headerArray} />);

        const row = screen.getAllByRole('row');
        expect(row[1]).toBeInTheDocument();
    });

    test('should calls onSelect when checkbox clicked', async () => {

        const onSelect = jest.fn();

        render(
            <Table
                rowList={rowArray}
                columnList={headerArray}
                onSelect={onSelect}
                enableCheckbox

            />
        );

        userEvent.click(screen.getByTestId('checkbox'));

        await waitFor(() => {
            expect(onSelect).toHaveBeenCalledWith(1);
        });
    });

    test('should calls onSelectAll when header checkbox clicked', async () => {

        const onSelectAll = jest.fn();

        render(
            <Table
                enableCheckbox
                onSelectAll={onSelectAll}
                rowList={[{ id: 1 }, { id: 2 }]}
                columnList={[{ title: "ID", name: "id" }]}
            />
        );

        userEvent.click(screen.getByTestId('header-checkbox'));

        await waitFor(() => {
            expect(onSelectAll).toHaveBeenCalledWith([1, 2]);
        });
    });

    test('should renders actions column', () => {

        render(
            <Table
                enableActions
                rowList={[{ id: 1, actions: <button type='button'>Edit</button> }]}
                columnList={[{ title: "ID", name: "id" }, { title: "Actions", name: "actions" }]}
            />
        );

        const button = screen.getByRole('button', { name: /edit/i });
        expect(button).toBeInTheDocument();
    });

    test('should renders checkboxes', () => {

        render(
            <Table
                enableCheckbox
                rowList={rowArray}
                columnList={headerArray}
            />
        );

        const checkbox = screen.getAllByRole('checkbox');

        expect(checkbox[1]).toBeInTheDocument();
    });

    test('should renders striped rows', () => {

        render(
            <Table
                striped
                rowList={[{ id: 1 }, { id: 2 }]}
                columnList={[{ title: "ID", name: "id" }]}
            />
        );

        const rows = screen.getAllByRole('row');

        expect(rows[1]).not.toHaveStyle(`background-color: #F6F6F6`);

        expect(rows[2]).toHaveStyle(`background-color: #F6F6F6`);
    });

    test('should renders custom styles', async () => {

        render(
            <Table
                className='tableStyle'
                enableCheckbox
                rowList={rowArray}
                columnList={headerArray}
            />
        );

        const table = screen.getByRole('table');

        expect(table).toHaveClass(`tableStyle`);
    });

    test('should not be called onSelect when clicking on a disabled row', async () => {

        const onSelect = jest.fn();

        render(
            <Table
                rowList={rowDisabledArray}
                columnList={headerArray}
                onSelect={onSelect}
                enableCheckbox
            />
        );

        userEvent.click(screen.getByTestId('checkbox'));

        await waitFor(() => {
            expect(onSelect).not.toHaveBeenCalledWith(1);
        });
    });

    test('should not be included disabled rows in the selected rows', async () => {
        
        const onSelectAll = jest.fn();

        render(
            <Table
                enableCheckbox
                onSelectAll={onSelectAll}
                rowList={[{ id: 1 }, { id: 2 }, {id: 3, disabled: true}]}
                columnList={[{ title: "ID", name: "id" }]}
            />
        );

        userEvent.click(screen.getByTestId('header-checkbox'));

        await waitFor(() => {
            expect(onSelectAll).toHaveBeenCalledWith([1, 2]);
        });
    })

    test('should return id when clicking on row', async () => {

        const rowClick = jest.fn();
        const onSelect = () => {};
        const onSelectAll = () => {};

        render(
            <Table
                enableCheckbox
                onSelect={onSelect}
                onSelectAll={onSelectAll}
                rowClick={rowClick}
                rowList={rowArray}
                columnList={headerArray}
            />
        );

        const rows = screen.getAllByRole('row');
        userEvent.click(rows[1]);

        await waitFor(() => {
            expect(rowClick).toHaveBeenCalledWith(1);
        });
    })
});



